import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/entities/company_financial_year_entity.dart';
import 'package:finance_app/src/entities/employment_type_entity.dart';
import 'package:finance_app/src/entities/martial_status_entity.dart';
import 'package:finance_app/src/entities/pass_type_entity.dart';
import 'package:finance_app/src/entities/payment_term_entity.dart';
import 'package:finance_app/src/entities/role_permission_entity.dart';
import 'package:finance_app/src/entities/salary_period_entity.dart';
import 'package:finance_app/src/entities/setting_app_entity.dart';
import 'package:finance_app/src/entities/setting_asset_category_entity.dart';
import 'package:finance_app/src/entities/setting_data_entity.dart';
import 'package:finance_app/src/utils/date_time_utils.dart';
import 'package:finance_app/src/utils/language_utils.dart';
import 'package:finance_app/src/widgets/select/normal_radio.dart';
import 'package:flutter/material.dart';

import 'default_bottom_sheet.dart';

// 选择标签
showFixedCategorySelectBottomSheet(
  BuildContext context,
  SettingAssetCategoryEntity currentSelect,
) async {
  SettingAssetCategoryEntity _currentSelect = currentSelect;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<SettingAssetCategoryEntity>(
      currentSelect: _currentSelect,
      onSelectValue: (data) {
        _currentSelect = data;
      },
      group: Config.settingData.assetCategory,
      buildDisplayName: (d) => d.name,
    ),
    title: S.current.category,
    isScrollControlled: true,
  );
  return _currentSelect;
}

//选择记录
showBankRecordsSelectBottomSheet(
  BuildContext context,
  String currentSelect,
) async {
  String _currentSelect = currentSelect;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<String>(
      currentSelect: _currentSelect,
      onSelectValue: (data) {
        _currentSelect = data;
      },
      group: ['All', 'Unmatched', 'Matched'],
      buildDisplayName: LanguageUtils.translateStatus,
    ),
    title: S.current.bank_records,
    isScrollControlled: true,
  );
  return _currentSelect;
}

showDateFormatSelectBottomSheet(
  BuildContext context,
  String currentSelect,
) async {
  String _currentSelect = currentSelect;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<String>(
      currentSelect: _currentSelect,
      onSelectValue: (data) {
        _currentSelect = data;
      },
      group: ['d MMM yyyy', 'dd/MM/yy'],
      buildDisplayName: (String text) => text.toUpperCase(),
    ),
    title: S.current.date_format,
    isScrollControlled: true,
  );
  return _currentSelect;
}

showLanguageSelectBottomSheet(
  BuildContext context,
  String currentSelect,
) async {
  String _currentSelect = currentSelect;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<String>(
      currentSelect: _currentSelect,
      onSelectValue: (data) {
        _currentSelect = data;
      },
      group: Config.languages,
      buildDisplayName: LanguageUtils.getLanguageName,
    ),
    title: S.current.language,
    isScrollControlled: true,
  );
  return _currentSelect;
}

showStatusSelectBottomSheet(
  BuildContext context,
  String currentSelect,
) async {
  String _currentSelect = currentSelect;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<String>(
      currentSelect: _currentSelect,
      onSelectValue: (data) {
        _currentSelect = data;
      },
      group: ['Active', 'Inactive', 'All'],
      buildDisplayName: LanguageUtils.translateStatus,
    ),
    title: S.current.status,
    isScrollControlled: true,
  );
  return _currentSelect;
}

showProductStatusSelectBottomSheet(
  BuildContext context,
  String currentSelect,
) async {
  String _currentSelect = currentSelect;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<String>(
      currentSelect: _currentSelect,
      onSelectValue: (data) {
        _currentSelect = data;
      },
      group: ['Active', 'Inactive', 'All'],
      buildDisplayName: LanguageUtils.translateStatus,
    ),
    title: S.current.products,
    isScrollControlled: true,
  );
  return _currentSelect;
}

//公司类型选择
showBusinessTypeSelectBottomSheet(
  BuildContext context,
  SettingAppBusinessType currentSelect,
) async {
  SettingAppBusinessType _currentSelect = currentSelect;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<SettingAppBusinessType>(
      currentSelect: _currentSelect,
      onSelectValue: (data) {
        _currentSelect = data;
      },
      group: Config.settingApp.businessType,
      buildDisplayName: (data) => data.name,
    ),
    title: S.current.business_type,
    isScrollControlled: true,
  );
  return _currentSelect;
}

//financial years
showFinancialYearSelectBottomSheet(
  BuildContext context,
  CompanyFinancialYearEntity currentSelect,
  List<CompanyFinancialYearEntity> groups,
) async {
  CompanyFinancialYearEntity _currentSelect = currentSelect;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<CompanyFinancialYearEntity>(
      currentSelect: _currentSelect,
      onSelectValue: (data) {
        _currentSelect = data;
      },
      group: groups,
      buildDisplayName: (data) => data.isCurrentYear
          ? S.current.current_financial_year
          : DateTimeUtils.formatFinancialYearDate(data.startDate, data.endDate),
    ),
    title: S.current.switch_financial_year,
    isScrollControlled: true,
  );
  return _currentSelect;
}

/// 选择结算方式
showSalaryPeriodSelectBottomSheet(
  BuildContext context,
  SalaryPeriodEntity currentSelect,
) async {
  SalaryPeriodEntity _currentSelect = currentSelect;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<SalaryPeriodEntity>(
      currentSelect: _currentSelect,
      onSelectValue: (data) {
        _currentSelect = data;
      },
      group: Config.settingData.salaryPeriod,
      buildDisplayName: (data) => data.name,
    ),
    title: S.current.salary_period,
    isScrollControlled: true,
  );
  return _currentSelect;
}

/// 选择雇佣类型
showEmploymentTypeSelectBottomSheet(
  BuildContext context,
  EmploymentTypeEntity currentSelect,
) async {
  EmploymentTypeEntity _currentSelect = currentSelect;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<EmploymentTypeEntity>(
      currentSelect: _currentSelect,
      onSelectValue: (data) {
        _currentSelect = data;
      },
      group: Config.settingData.employmentType,
      buildDisplayName: (data) => data.name,
    ),
    title: S.current.employment_type,
    isScrollControlled: true,
  );
  return _currentSelect;
}

/// 选择密码类型
showPassTypeSelectBottomSheet(
  BuildContext context,
  PassTypeEntity currentSelect,
) async {
  PassTypeEntity _currentSelect = currentSelect;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<PassTypeEntity>(
      currentSelect: _currentSelect,
      onSelectValue: (data) {
        _currentSelect = data;
      },
      group: Config.settingData.passType,
      buildDisplayName: (data) => data.name,
    ),
    title: S.current.pass_type,
    isScrollControlled: true,
  );
  return _currentSelect;
}

/// 选择婚况
showMaritalStatusSelectBottomSheet(
  BuildContext context,
  MartialStatusEntity currentSelect,
) async {
  MartialStatusEntity _currentSelect = currentSelect;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<MartialStatusEntity>(
      currentSelect: _currentSelect,
      onSelectValue: (data) {
        _currentSelect = data;
      },
      group: Config.settingData.martialStatus,
      buildDisplayName: (data) => data.name,
    ),
    title: S.current.marital_status,
    isScrollControlled: true,
  );
  return _currentSelect;
}

/// 选择血统
showRaceSelectBottomSheet(
  BuildContext context,
  String currentSelect,
) async {
  String _currentSelect = currentSelect;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<String>(
      currentSelect: _currentSelect,
      onSelectValue: (data) {
        _currentSelect = data;
      },
      group: [
        'Chinese',
        'Malay',
        'Indian',
        'Others',
      ],
      buildDisplayName: defaultBuildDisplayName,
    ),
    title: S.current.race,
    isScrollControlled: true,
  );
  return _currentSelect;
}

/// 选择性别
showGenderSelectBottomSheet(
  BuildContext context,
  String currentSelect,
) async {
  String _currentSelect = currentSelect;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<String>(
      currentSelect: _currentSelect,
      onSelectValue: (data) {
        _currentSelect = data;
      },
      group: [
        'Male',
        'Female',
      ],
      buildDisplayName: LanguageUtils.translateStatus,
    ),
    title: S.current.gender,
    isScrollControlled: true,
  );
  return _currentSelect;
}

/// 添加员工状态
showEmploymentStatusBottomSheet(
  BuildContext context,
  String status,
) async {
  String _status = status;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<String>(
      currentSelect: _status,
      onSelectValue: (data) {
        _status = data;
      },
      group: [
        'Existing',
        'Left',
        'All',
      ],
      buildDisplayName: LanguageUtils.translateStatus,
    ),
    title: S.current.employment_status,
    isScrollControlled: true,
  );
  return _status;
}

/// 添加Gst
showGstInclusiveBottomSheet(
  BuildContext context,
  bool gstInclusive,
) async {
  bool _currentSelectCode = gstInclusive;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<bool>(
      currentSelect: gstInclusive,
      onSelectValue: (data) {
        _currentSelectCode = data;
      },
      group: [true, false],
      buildDisplayName: (value) =>
          '${value == true ? S.current.yes : S.current.no}',
    ),
    title: S.current.gst_inclusive,
    isScrollControlled: true,
  );
  return _currentSelectCode;
}

/// 添加Gst
showGstRateBottomSheet(
  BuildContext context,
  SettingDataTax gstRate,
) async {
  SettingDataTax _currentSelectCode = gstRate;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<SettingDataTax>(
      currentSelect: gstRate,
      onSelectValue: (data) {
        _currentSelectCode = data;
      },
      group: List<SettingDataTax>.from(Config.settingData.tax),
      buildDisplayName: (value) => '${value.displayName}(${value.name})',
    ),
    title: S.current.gst_rate,
    isScrollControlled: true,
  );
  return _currentSelectCode;
}

/// 添加支付方式
showPaidUsingBottomSheet(
  BuildContext context,
  SettingDataPaidUsing paidUsing,
) async {
  SettingDataPaidUsing _currentSelectCode = paidUsing;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<SettingDataPaidUsing>(
      currentSelect: paidUsing,
      onSelectValue: (data) {
        _currentSelectCode = data;
      },
      group: List<SettingDataPaidUsing>.from(Config.settingData.paidUsing),
      buildDisplayName: (value) => value.name,
    ),
    title: S.current.paid_using,
    isScrollControlled: true,
  );
  return _currentSelectCode;
}

/// 添加单位
showUnitOfMeasurementBottomSheet(
  BuildContext context,
  SettingDataUnitType paymentMethod,
) async {
  SettingDataUnitType _currentSelectCode = paymentMethod;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<SettingDataUnitType>(
      currentSelect: paymentMethod,
      onSelectValue: (data) {
        _currentSelectCode = data;
      },
      group: List<SettingDataUnitType>.from(Config.settingData.unitType),
      buildDisplayName: (value) => value.name,
    ),
    title: S.current.unit_of_measurement,
    isScrollControlled: true,
  );
  return _currentSelectCode;
}

showPaymentMethodBottomSheet(
  BuildContext context,
  SettingDataPaymentType paymentMethod, {
  String filterKey,
}) async {
  SettingDataPaymentType _currentSelectCode = paymentMethod;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<SettingDataPaymentType>(
      currentSelect: paymentMethod,
      onSelectValue: (data) {
        _currentSelectCode = data;
      },
      group: List<SettingDataPaymentType>.from(Config.settingData.paymentType)
        ..removeWhere((element) => element.key == filterKey),
      buildDisplayName: (value) => value.name,
    ),
    title: S.current.payment_method,
    isScrollControlled: true,
  );
  return _currentSelectCode;
}

showPaymentTermBottomSheet(
  BuildContext context,
  PaymentTermEntity paymentTerm, {
  String filterKey,
}) async {
  PaymentTermEntity _currentSelectCode = paymentTerm;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<PaymentTermEntity>(
      currentSelect: paymentTerm,
      onSelectValue: (data) {
        _currentSelectCode = data;
      },
      group: List<PaymentTermEntity>.from(Config.paymentTerms),
      // ..removeWhere((element) => element.key == filterKey),
      buildDisplayName: (value) => value.name,
    ),
    title: S.current.payment_term,
    isScrollControlled: true,
  );
  return _currentSelectCode;
}

showRolesBottomSheet(
  BuildContext context,
  List<RolePermissionEntity> roles, {
  String filterKey,
  @required String title,
}) async {
  RolePermissionEntity _currentSelectCode;
  await showDefaultBottomSheet(
    context,
    child: ListSelectBottomSheet<RolePermissionEntity>(
      currentSelect: null,
      onSelectValue: (data) {
        _currentSelectCode = data;
      },
      group: roles,
      // ..removeWhere((element) => element.key == filterKey),
      buildDisplayName: (value) => value.name,
    ),
    title: title,
    isScrollControlled: true,
  );
  return _currentSelectCode;
}

typedef BuildDisplayName<T> = String Function(T value);

String defaultBuildDisplayName<T>(T value) => value as String;

class ListSelectBottomSheet<T> extends StatefulWidget {
  final List<T> group;
  final T currentSelect;
  final ValueChanged<T> onSelectValue;
  final BuildDisplayName<T> buildDisplayName;
  final bool isList;

  const ListSelectBottomSheet(
      {Key key,
      @required this.group,
      @required this.onSelectValue,
      @required this.currentSelect,
      @required this.buildDisplayName,
      this.isList = false})
      : super(key: key);

  @override
  _ListSelectBottomSheetState<T> createState() =>
      _ListSelectBottomSheetState<T>();
}

class _ListSelectBottomSheetState<T> extends State<ListSelectBottomSheet<T>> {
  T _currentSelect;
  BuildDisplayName<T> _buildDisplayName;

  @override
  void initState() {
    super.initState();
    _currentSelect = widget.currentSelect;
    _buildDisplayName = widget.buildDisplayName;
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> children = [
      SizedBox(
        height: getDp(17),
        width: MediaQuery.of(context).size.width,
      ),
      Padding(
        padding: EdgeInsets.symmetric(
          horizontal: getDp(10),
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisAlignment: MainAxisAlignment.start,
          mainAxisSize: MainAxisSize.min,
          children: widget.group
              .map((e) => PressedOpacityButton(
                    onPressed: () => onChangeSelect(e),
                    padding: EdgeInsets.symmetric(
                      vertical: getDp(10),
                      horizontal: getDp(34),
                    ),
                    child: NormalRadio(
                      title: _buildDisplayName?.call(e),
                      isSelect: _currentSelect == e,
                      isFix: true,
                    ),
                  ))
              .toList(),
        ),
      ),
    ];
    if (widget.isList == true) {
      double height = MediaQuery.of(context).size.height / 2;
      return SizedBox(
        height: height,
        child: ListView(
          children: children,
        ),
      );
    } else {
      return Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisSize: MainAxisSize.min,
        children: children,
      );
    }
  }

  void onChangeSelect(e) {
    if (_currentSelect == e) return;
    setState(() {
      _currentSelect = e;
    });
    widget.onSelectValue?.call(_currentSelect);
    Navigator.of(context).pop();
  }
}
